import {MicroAppModule} from "./MicroAppModule";
import {uuid} from "@peryl/utils/uuid";
import {iMicroAppPageMethods, iMicroAppTabMethods, iMicroPageMeta, iMicroTabMeta} from "@peryl/micro-web";
import {delay} from "@peryl/react-compose";
import {deepcopy} from "@peryl/utils/deepcopy";

export const microAppTabs = MicroAppModule.createRegistration((option) => {

  const { state, hooks } = option;

  const pageMethods: iMicroAppPageMethods = {
    /**
     * 在某个tab下push一个新页面
     * @author  韦胜健
     * @date    2024/1/31 14:21
     */
    pushPage: (tabMeta: iMicroTabMeta, param: { path: string, data?: any }) => {
      const pageMeta: iMicroPageMeta = {
        id: `micro_page_${uuid()}`,
        path: param.path,
        data: param.data,
        init: true,
        show: false,
      };
      tabMeta.pages.push(pageMeta);
      pageMethods.showPage(pageMeta);
    },
    /**
     * 显示页面
     * @author  韦胜健
     * @date    2024/1/31 14:21
     */
    showPage: (pageMeta: iMicroPageMeta | null | undefined) => {
      const currentShowPage = state.tabs.reduce((prev, item) => (prev.push(...item.pages), prev), [] as iMicroPageMeta[]).find(i => i.show && i.init);
      if (!!currentShowPage) {
        if (!!pageMeta && currentShowPage.id === pageMeta.id) {
          option.cache.save();
          return;
        } else {
          currentShowPage.show = false;
        }
      }
      if (!!pageMeta) {
        pageMeta.show = true;
      }
      hooks.onPagesChange.exec(undefined);
    },
  };

  const tabMethods: iMicroAppTabMethods = {
    /**
     * 打开一个新的tab
     * 会根据id寻找tab是否已经打开，没有打开的情况下会打开一个新的tab；
     * 已经打开的tab，如果设置refresh:true则会重新渲染tab；未设置则会显示这个tab最后一个页面
     * @author  韦胜健
     * @date    2024/1/31 14:18
     */
    openTab: async (param: { id?: string, label: string, tabData?: any, path: string, data?: any, refresh?: boolean, icon?: string, insertIndex?: number }) => {
      const tabMeta: iMicroTabMeta = {
        id: param.id || `micro_tab_${uuid()}`,
        icon: param.icon,
        label: param.label,
        data: param.tabData,
        page: { path: param.path, data: param.data },
        pages: [],
        sourceParam: param,
      };
      const existTabMetaIndex = state.tabs.findIndex(i => i.id === tabMeta.id);
      if (existTabMetaIndex > -1) {
        /*tab已经存在*/
        if (param.refresh) {
          /*刷新tab*/
          state.tabs.splice(existTabMetaIndex, 1, tabMeta);
          pageMethods.pushPage(tabMeta, { path: param.path, data: param.data });
          return;
        } else {
          /*显示tab*/
          tabMethods.showTab(state.tabs[existTabMetaIndex]);
          return;
        }
      } else {
        /*打开新tab*/
        if (param.insertIndex == null) {
          state.tabs.push(tabMeta);
        } else {
          state.tabs.splice(param.insertIndex, 0, tabMeta);
        }
        pageMethods.pushPage(tabMeta, { path: param.path, data: param.data });
      }
    },
    /**
     * 显示tab
     * @author  韦胜健
     * @date    2024/1/31 14:21
     */
    showTab: (tabMeta: iMicroTabMeta | null | undefined) => {
      if (!tabMeta) {
        pageMethods.showPage(undefined);
      } else {
        if (tabMeta.pages.length) {
          pageMethods.showPage(tabMeta.pages[tabMeta.pages.length - 1]);
        } else {
          pageMethods.pushPage(tabMeta, { path: tabMeta.page.path, data: tabMeta.page.data });
        }
      }
    },
    /**
     * 关闭tab
     * @author  韦胜健
     * @date    2024/1/31 14:29
     */
    closeTab: (tabMetaOrId: string | iMicroTabMeta) => {
      // if (state.tabs.length <= 1) {return;}
      const tabId = typeof tabMetaOrId === "string" ? tabMetaOrId : tabMetaOrId.id;
      const tabIndex = state.tabs.findIndex((i) => i.id === tabId);
      if (tabIndex === -1) {
        return;
      }
      const curShowTabIndex = state.tabs.findIndex(i => i.pages.find(i => i.show));
      const nextTabIndex = curShowTabIndex == tabIndex ? (tabIndex === 0 ? 0 : tabIndex - 1) : (curShowTabIndex < tabIndex ? curShowTabIndex : curShowTabIndex - 1);
      state.tabs.splice(tabIndex, 1);
      tabMethods.showTab(state.tabs?.[nextTabIndex]);
    },
    copyTab: (tabMetaOrId: string | iMicroTabMeta) => {
      const tabId = typeof tabMetaOrId === "string" ? tabMetaOrId : tabMetaOrId.id;
      let tabMetaIndex = state.tabs.findIndex((i) => i.id === tabId);
      let tabMeta = tabMetaIndex == -1 ? null : state.tabs[tabMetaIndex];
      if (!tabMeta) {return;}
      const sourceParam = deepcopy(tabMeta.sourceParam);
      sourceParam.id = uuid();
      sourceParam.insertIndex = tabMetaIndex + 1;
      tabMethods.openTab(sourceParam);
    },
    /**
     * 刷新tab内容
     * @author  韦胜健
     * @date    2024/1/31 14:34
     */
    refreshTab: async (tabMeta: iMicroTabMeta) => {
      tabMeta.pages = [];
      await delay(23);
      pageMethods.pushPage(tabMeta, { path: tabMeta.page.path, data: tabMeta.page.data });
    },
    closeTabs: (tabOrIds) => {
      let prevActiveTabIndex = state.tabs.findIndex(i => i.pages.find(i => i.show));
      let prevActiveTab = state.tabs[prevActiveTabIndex];

      const ids = tabOrIds.map(i => typeof i === "string" ? i : i.id);
      const tabs = state.tabs.filter(tab => ids.findIndex(i => i === tab.id) === -1);
      if (tabs.length === state.tabs.length) {
        return;
      }
      state.tabs = tabs;

      /*显示的tab还在，仅删除其他tab*/
      if (!!state.tabs.find(i => i.id === prevActiveTab.id)) {
        return;
      }

      /*显示的tab已经不在了，显示上一个tab*/
      let nextActiveTabIndex = prevActiveTabIndex <= 0 ? 0 : prevActiveTabIndex - 1;
      if (nextActiveTabIndex > state.tabs.length) {
        nextActiveTabIndex = state.tabs.length - 1;
      }
      tabMethods.showTab(state.tabs?.[nextActiveTabIndex]);
    },
    closeLeftTabs: (tabOrId) => {
      const id = typeof tabOrId === "string" ? tabOrId : tabOrId.id;
      const index = state.tabs.findIndex(i => i.id === id);
      if (index === -1) {
        return;
      }
      const closeTabs = state.tabs.filter((_, idx) => idx < index);
      tabMethods.closeTabs(closeTabs);
      hooks.onPagesChange.exec(undefined);
    },
    closeRightTabs: (tabOrId) => {
      const id = typeof tabOrId === "string" ? tabOrId : tabOrId.id;
      const index = state.tabs.findIndex(i => i.id === id);
      if (index === -1) {
        return;
      }
      const closeTabs = state.tabs.filter((_, idx) => idx > index);
      tabMethods.closeTabs(closeTabs);
      hooks.onPagesChange.exec(undefined);
    },
    closeOtherTabs: (tabOrId) => {
      const id = typeof tabOrId === "string" ? tabOrId : tabOrId.id;
      const index = state.tabs.findIndex(i => i.id === id);
      if (index === -1) {
        return;
      }
      const closeTabs = state.tabs.filter((_, idx) => idx != index);
      tabMethods.closeTabs(closeTabs);
      hooks.onPagesChange.exec(undefined);
    },
  };

  Object.assign(option, tabMethods);
  Object.assign(option, pageMethods);
});
